package com.example.module_course.common

import android.content.Intent
import android.media.MediaMetadataRetriever
import android.os.Bundle
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.TabPosition
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.blankj.utilcode.util.LogUtils
import com.example.module_course.R
import com.fenghuajueli.libbasecoreui.utils.TimeUtils
import java.net.HttpURLConnection
import java.net.URL

/**
 * Create by linyue
 * Time:2022/10/27 11:42
 */

inline fun FragmentActivity.launchActivity(clazz: Class<*>, lambda: Bundle.() -> Unit = {}) {
    val itt = Intent(this, clazz)
    val bundle = Bundle()
    lambda.invoke(bundle)
    itt.putExtras(bundle)
    startActivity(itt)
}

inline fun Fragment.launchActivity(clazz: Class<*>, lambda: Bundle.() -> Unit = {}) {
    val itt = Intent(requireContext(), clazz)
    val bundle = Bundle()
    lambda.invoke(bundle)
    itt.putExtras(bundle)
    startActivity(itt)
}

@Composable
fun TopTitleBar(title: String, onBack: () -> Unit) {
    ConstraintLayout(
        modifier = Modifier
            .statusBarsPadding()
            .fillMaxWidth()
            .height(48.dp)
    ) {
        val (backRef, titleRef) = createRefs()

        Image(
            painter = painterResource(id = R.mipmap.icon_back_black),
            contentDescription = null,
            modifier = Modifier
                .padding(horizontal = 5.dp)
                .constrainAs(backRef) {
                    start.linkTo(parent.start, 16.dp)
                    centerVerticallyTo(parent)
                }
                .clickable {
                    onBack.invoke()
                }
        )

        Text(
            text = title,
            style = TextStyle(
                color = Color(0xFF333333),
                fontSize = 20.sp,
                fontWeight = FontWeight.Medium
            ),
            textAlign = TextAlign.Center,
            modifier = Modifier
                .constrainAs(titleRef) {
                    centerHorizontallyTo(parent)
                    centerVerticallyTo(parent)
                }
        )
    }
}


fun Modifier.customTabIndicatorOffset(
    currentTabPosition: TabPosition
): Modifier = composed(
    inspectorInfo = debugInspectorInfo {
        name = "tabIndicatorOffset"
        value = currentTabPosition
    }
) {
    val currentTabWidth by animateDpAsState(
        targetValue = currentTabPosition.width,
        animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing), label = ""
    )
    val indicatorOffset by animateDpAsState(
        targetValue = currentTabPosition.left,
        animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing), label = ""
    )
    LogUtils.e(indicatorOffset, currentTabWidth)
    fillMaxWidth()
        .wrapContentSize(Alignment.BottomStart)
        .offset(indicatorOffset + currentTabWidth / 2 - 12.dp)
        .width(24.dp)
        .height(4.dp)
        .clip(RoundedCornerShape(2.dp))
        .background(Brush.horizontalGradient(0.0f to Color(0xFF4E86FF), 0.5f to Color(0xFF6976FF), 1.0f to Color(0xFF8565FF)))
}

internal val comparator = Comparator<String> { a, b ->
    // 解析月份
    val monthA = parseMonth(a)
    val monthB = parseMonth(b)

    // 如果月份不同，按月份排序
    if (monthA != monthB) {
        return@Comparator monthA.compareTo(monthB)
    }

    // 解析编号
    val numberA = parseNumber(a)
    val numberB = parseNumber(b)

    // 如果月份相同，按编号排序
    return@Comparator numberA.compareTo(numberB)
}

// 解析月份（月份总是中文的“一月”到“十二月”）
private fun parseMonth(s: String): Int {
    val monthPattern = Regex("(\\p{Han}+月)")
    val match = monthPattern.find(s) ?: throw IllegalArgumentException("No month found in string: $s")
    val monthStr = match.groupValues[1].trim()
    val months = mapOf(
        "一月" to 1, "二月" to 2, "三月" to 3, "四月" to 4,
        "五月" to 5, "六月" to 6, "七月" to 7, "八月" to 8,
        "九月" to 9, "十月" to 10, "十一月" to 11, "十二月" to 12
    )
    return months[monthStr] ?: 0
}

// 解析编号（编号总是一个整数）
private fun parseNumber(s: String): Int {
    val numberPattern = Regex("(\\d+)")
    return numberPattern.find(s)?.groupValues?.get(1)?.toInt() ?: 0
}

internal val String.fileSize: Long
    get() {
        var connection: HttpURLConnection? = null
        try {
            val urlObj = URL(this)
            connection = urlObj.openConnection() as HttpURLConnection
            connection.requestMethod = "HEAD"
            val contentLength = connection.getHeaderField("Content-Length")
            return contentLength?.toLongOrNull() ?: 0L
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            connection?.disconnect()
        }
        return 0L
    }

private val Int.BYTE: Int
    get() = this

private val Int.KB: Int
    get() = 1024 * BYTE

private val Int.MB: Int
    get() = 1024 * KB

private val Int.GB: Int
    get() = 1024 * MB

internal fun Long.byteToFitMemorySize(precision: Int = 1): String {
    require(precision >= 0) { "小数点精度必须大于0" }
    return if (this < 0) {
        throw IllegalArgumentException("byteSize shouldn't be less than zero!")
    } else if (this < 1.KB) {
        String.format("%." + precision + "fB", toDouble())
    } else if (this < 1.MB) {
        String.format("%." + precision + "fKB", toDouble() / 1.KB)
    } else if (this < 1.GB) {
        String.format("%." + precision + "fMB", toDouble() / 1.MB)
    } else {
        String.format("%." + precision + "fGB", toDouble() / 1.GB)
    }
}

internal val String.duration: String
    get() {
        val retriever = MediaMetadataRetriever()
        var duration = "00:00:00"
        runCatching {
            retriever.setDataSource(this)
            val d = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull() ?: 0L
            duration = TimeUtils.msecToTime(d)
        }
        retriever.release()
        return duration
    }